﻿using System;
using umbraco.DataLayer;

namespace UComment.Domain
{
    public class Comment
    {
        public delegate void CommentCreatedEventHandler(Comment sender, EventArgs e);
        public delegate void CommentDeletedEventHandler(Comment sender, EventArgs e);
        public delegate void CommentSpamEventHandler(Comment sender, EventArgs e);
        public delegate void CommentApprovedEventHandler(Comment sender, EventArgs e);

        public static event CommentCreatedEventHandler CommentCreated;
        public static event CommentDeletedEventHandler CommentDeleted;
        public static event CommentSpamEventHandler CommentSpam;
        public static event CommentApprovedEventHandler CommentApproved;

        protected virtual void OnCommentCreated(EventArgs e)
        {
            if (CommentCreated != null) CommentCreated(this, e);
        }

        protected virtual void OnCommentSpam(EventArgs e)
        {
            if (CommentSpam != null) CommentSpam(this, e);
        }

        protected virtual void OnCommentApproved(EventArgs e)
        {
            if (CommentApproved != null) CommentApproved(this, e);
        }

        protected virtual void OnCommentDelete(EventArgs e)
        {
            if (CommentDeleted != null) CommentDeleted(this, e);
        }


        public int Id { get; set; }
        public int ParentNodeId { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public string Website { get; set; }
        public bool Spam { get; set; }
        public bool Approved { get; set; }
        public DateTime Created { get; set; }
        public string CommenText { get; set; }

        public Comment(int id)
        {
            Id = id;
            var sqlHelper = DataLayerHelper.CreateSqlHelper(umbraco.GlobalSettings.DbDSN);
            var reader = sqlHelper.ExecuteReader("select * from Comment where id = @id",
                                                 sqlHelper.CreateParameter("@id", id));

            if(!reader.HasRecords) throw new Exception(string.Format("Comment with id {0} was not found", id));
           
            reader.Read();
            
            Name = reader.GetString("name");
            ParentNodeId = reader.GetInt("nodeid");
            Email = reader.GetString("email");
            Website = reader.GetString("website");
            Approved = reader.GetBoolean("approved");
            Spam = reader.GetBoolean("Spam");
            Created = reader.GetDateTime("created");
            CommenText = reader.GetString("comment");
        }

        private Comment()
        {
        }

        /// <summary>
        /// Set as approved, mark as Not Spam - ignore HAM status
        /// </summary>
        public void MarkAsApproved()
        {
            var sqlHelper = DataLayerHelper.CreateSqlHelper(umbraco.GlobalSettings.DbDSN);
            sqlHelper.ExecuteNonQuery(
                 "update comment set approved = 1, spam = 0 where id = @id",
                 sqlHelper.CreateParameter("@id", Id));

            OnCommentApproved(EventArgs.Empty);
        }

        /// <summary>
        /// Remove approval status. Ignore Spam and Ham states
        /// </summary>
        public void MarkAsNotApproved()
        {
            var sqlHelper = DataLayerHelper.CreateSqlHelper(umbraco.GlobalSettings.DbDSN);
            sqlHelper.ExecuteNonQuery(
                 "update comment set approved = 0 where id = @id",
                 sqlHelper.CreateParameter("@id", Id));

            OnCommentApproved(EventArgs.Empty);
        }
        


        /// <summary>
        /// Spam cannot be ham or approved
        /// </summary>
        public void MarkAsSpam()
        {
            var sqlHelper = DataLayerHelper.CreateSqlHelper(umbraco.GlobalSettings.DbDSN);
            sqlHelper.ExecuteNonQuery(
                 "update comment set spam = 1, ham = 0, approved = 0 where id = @id",
                 sqlHelper.CreateParameter("@id", Id));
            
            OnCommentSpam(EventArgs.Empty);
        }


        /// <summary>
        /// Ham is "not spam" - approved comments from Akismet. 
        /// </summary>
        public void MarkAsHam()
        {
            var sqlHelper = DataLayerHelper.CreateSqlHelper(umbraco.GlobalSettings.DbDSN);
            sqlHelper.ExecuteNonQuery(
               "update comment set spam = 0, ham = 1 where id = @id",
               sqlHelper.CreateParameter("@id", Id));
        }

        public void Delete()
        {
            if (Id < 1)  return;

            var sqlHelper = DataLayerHelper.CreateSqlHelper(umbraco.GlobalSettings.DbDSN);
            sqlHelper.ExecuteNonQuery("delete from comment where id = @id", sqlHelper.CreateParameter("@id", Id));

            Id = -1;
            OnCommentDelete(EventArgs.Empty);
        }

        public static Comment MakeNew(int parentNodeId, string name, string email, string website, bool approved, bool spam, DateTime created, string commentText) {
            
            var c = new Comment
                        {
                            ParentNodeId = parentNodeId,
                            Name = name,
                            Email = email,
                            Website = website,
                            Approved = approved,
                            Spam = spam,
                            Created = created,
                            CommenText = commentText
                        };

            var sqlHelper = DataLayerHelper.CreateSqlHelper(umbraco.GlobalSettings.DbDSN);

            c.Id = sqlHelper.ExecuteScalar<int>(
                @"insert into Comment(mainid,nodeid,name,email,website,comment,approved,spam,created) 
                        values(@mainid,@nodeid,@name,@email,@website,@comment,@approved,@spam,@created)",
                 sqlHelper.CreateParameter("@mainid", -1),
                sqlHelper.CreateParameter("@nodeid", c.ParentNodeId),
                sqlHelper.CreateParameter("@name", c.Name),
                sqlHelper.CreateParameter("@email", c.Email),
                sqlHelper.CreateParameter("@website", c.Website),
                sqlHelper.CreateParameter("@comment", c.CommenText),
                sqlHelper.CreateParameter("@approved", c.Approved),
                sqlHelper.CreateParameter("@spam", c.Spam),
                sqlHelper.CreateParameter("@created", c.Created));

            c.OnCommentCreated(EventArgs.Empty);

            if (c.Spam)
            {
                c.OnCommentSpam(EventArgs.Empty);
            }

            if (c.Approved)
            {
                c.OnCommentApproved(EventArgs.Empty);
            }

            return c;
        }

        public override string ToString()
        {
            return @"ParentNodeId " + ParentNodeId + @"
            Name " + Name + @"
            Email " + Email + @"
            Website " + Website + @"
            Approved " + Approved + @"
            Spam " + Spam + @"
            Created "+ Created + @"
            CommenText " + CommenText + Environment.NewLine;
        }
    }
}